package com.woniuxy.service.impl;

import com.woniuxy.entity.*;
import com.woniuxy.exception.NotFullTimeException;
import com.woniuxy.mapper.*;
import com.woniuxy.service.ActiveService;
import com.woniuxy.util.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class ActiveServiceImpl implements ActiveService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Resource
    private ActivityMapper activityMapper;
    @Resource
    private ActivityTypeMapper activityTypeMapper;
    @Resource
    private CampMapper campMapper;
    @Override
    public List<Object> selectAllCampAndTypes() throws Exception {
        List<Object> list = new ArrayList<>();
        List<Camp> camps = campMapper.selectByExample(null);
        List<ActivityType> types = activityTypeMapper.selectByExample(null);
        list.add(camps);
        list.add(types);
        return list;
    }

    @Override
    public List<Map<String, Object>> selectAllActive(Page page, Integer campId, Integer typeId, Integer status) throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        map.put("number",page.getNumber());
        map.put("typeId" ,typeId);
        map.put("campId" , campId);
        map.put("status" ,status);
        map.put("start" , (page.getPageIndex()-1)* page.getNumber());

        List<Map<String,Object>> list = activityMapper.selectAllActive(map);
        return list;
    }

    @Override
    public int selectCount(Integer campId, Integer typeId, Integer status) throws Exception {
        ActivityExample example = new ActivityExample();
        ActivityExample.Criteria criteria = example.createCriteria();
        if(campId != null) criteria.andCampIdEqualTo(campId);

        if(typeId != null) criteria.andTypeIdEqualTo(typeId);

        if (status != null) criteria.andStatusEqualTo(status);

        long count = activityMapper.countByExample(example);
        return (int) count;
    }

    @Resource
    private ImgMapper imgMapper;
    @Override
    public void insertActivity(Activity activity, String[] url) throws Exception{
        activity.setStatus(0);
        activityMapper.insertSelective(activity);

        Date time = activity.getTime();
        Instant now = Instant.now();
        long redisTime = ChronoUnit.MINUTES.between(now,Instant.ofEpochMilli(time.getTime()));

        System.out.println(redisTime);
        if(redisTime <= 120)
            throw new NotFullTimeException("必须拥有2个小时以上的报名时间");

        String key = "activity#"+activity.getActId();
        ValueOperations forValue = redisTemplate.opsForValue();
        forValue.set(key,activity.getTime().toString(),redisTime, TimeUnit.MINUTES);


        Integer actId = activity.getActId();
        insertActImgs(url, actId);
    }

    private void insertActImgs(String[] url, Integer actId) {
        if(url == null){
            return;
        }
        for (String u:url
             ) {
            Img img = new Img();
            img.setOtherId(actId);
            img.setTypeId(7);
            img.setUrl(u);
            imgMapper.insertSelective(img);
        }
    }

    @Override
    public void deleteActActiveById(Integer actId) throws Exception {
        activityMapper.deleteByPrimaryKey(actId);
        if (redisTemplate.hasKey("activity#"+actId)){
            redisTemplate.delete("activity#"+actId);
        }
    }

    @Override
    public void updateActiveById(Activity activity, Integer[] deleteImgId, String[] url) throws Exception {
        activityMapper.updateByPrimaryKeySelective(activity);
        Integer actId = activity.getActId();
        insertActImgs(url, actId);
        if(deleteImgId != null){
            for (Integer i: deleteImgId
            ) {
                imgMapper.deleteByPrimaryKey(i);
            }
        }

        if (redisTemplate.hasKey("activity#"+actId)){
            System.out.println("xiugaile ");
//            如果时间发生了变化，则出现设置过期时间
            System.out.println(activity.getTime().toString());
            System.out.println(redisTemplate.opsForValue().get("activity#"+actId));
            if(!activity.getTime().toString().equals(redisTemplate.opsForValue().get("activity#"+actId))){
                System.out.println("redis");
                Instant now = Instant.now();
                long redisTime = ChronoUnit.MINUTES.between(now,Instant.ofEpochMilli(activity.getTime().getTime()));
                String key = "activity#"+activity.getActId();
                ValueOperations forValue = redisTemplate.opsForValue();
                forValue.set(key,activity.getTime().toString(),redisTime + 1, TimeUnit.MINUTES);
            }
        }
    }

    @Override
    public void updateActiveStatusById(Integer actId) throws Exception {
        Activity activity = new Activity();
        activity.setStatus(1);
        activity.setActId(actId);
        activityMapper.updateByPrimaryKeySelective(activity);
    }
    @Autowired
    private ActivityOrderMapper activityOrderMapper;
    @Override
    public int selectOrderCount(Integer campId, Integer actId, Integer status) throws Exception {
        ActivityOrderExample example = new ActivityOrderExample();
        ActivityOrderExample.Criteria criteria = example.createCriteria();
        if(campId != null) criteria.andCampIdEqualTo(campId);
        if(actId != null) criteria.andActIdEqualTo(actId);
        if(status != null) criteria.andStatusEqualTo(status);
        long count = activityOrderMapper.countByExample(example);


        return (int) count;
    }

    @Override
    public List<Map<String, Object>> selectAllActOrderCampAndTypes(Page page, Integer campId, Integer actId, Integer status) throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        map.put("number",page.getNumber());
        map.put("actId" ,actId);
        map.put("campId" , campId);
        map.put("status" ,status);
        map.put("start" , (page.getPageIndex()-1)* page.getNumber());

        List<Map<String,Object>> list =  activityOrderMapper.selectAllActOrderCampAndTypes(map);



        return list;
    }


}
